package com.heisen.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.heisen.base.exception.RRException;
import com.heisen.database.service.impl.SuperServiceImpl;
import com.heisen.system.dto.MenuDto;
import com.heisen.system.entity.Menu;
import com.heisen.system.mapper.MenuMapper;
import com.heisen.system.query.MenuQuery;
import com.heisen.system.service.IMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heisen.system.vo.MenuViewVo;
import com.heisen.system.vo.RouterMetaVo;
import com.heisen.system.vo.VueRouter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 菜单表 服务实现类
 * </p>
 *
 * @author sen
 * @since 2023-12-24
 */
@Service
public class MenuServiceImpl extends SuperServiceImpl<MenuMapper,Menu, MenuQuery> implements IMenuService {

    /**
     *  菜单list
     * @return
     */
    public List<Menu> menuList(Integer type) {
        QueryWrapper<Menu> wq = new QueryWrapper<>();
        if(type !=null )    wq.eq(Menu.TYPE,type);
        return  this.baseMapper.selectList(wq);
    }

    /**
     *  查找user 权限
     * @param username
     * @return
     */
    @Override
    public List<Menu> findUserPermissions(String username) {
        return this.baseMapper.findUserPermissions(username);
    }

    @Override
    public List<VueRouter<Menu>> getUserRouters(String username) {
        if(StringUtils.isEmpty(username)) throw new RRException("username 为空");
        List<VueRouter<Menu>> routes = new ArrayList<>();
        List<Menu> menus = this.baseMapper.findUserMenus(username);

        for (Menu menu : menus) {
            VueRouter<Menu> route = new VueRouter<>();
            route.setId(String.valueOf(menu.getId()));
            route.setParentId(String.valueOf(menu.getParentId()));
            route.setPath(menu.getPath());
            route.setComponent(menu.getComponent());
            route.setName(menu.getMenuName());
            route.setMeta(new RouterMetaVo(menu.getMenuName(), menu.getIcon()));
            routes.add(route);
        }

        return buildVueRouter(routes);
    }

    /**
     * 获取所有树状菜单和按钮
     * @param username
     * @return
     */
    @Override
    public List<MenuViewVo> findMetaView(String username ,Integer menuType) {
        if(StringUtils.isEmpty(username)) throw new RRException("username 为空");
        List<MenuViewVo> treeMenus = new ArrayList<>();
        List<Menu> menus = menuList( menuType);
        ArrayList<MenuViewVo> sysMenuViewVos = new ArrayList<>();

        for (Menu menu : menus) {
            MenuViewVo menuVo = new MenuViewVo();
            BeanUtils.copyProperties(menu,menuVo);
            sysMenuViewVos.add(menuVo);
        }


        for (MenuViewVo menu : sysMenuViewVos) {
            Long parentId = menu.getParentId();
            if (parentId == null || parentId == 0) {
                treeMenus.add(menu);
                continue;
            }

            for (MenuViewVo prentMenu : sysMenuViewVos) {
                Long id = prentMenu.getMenuId();

                if (id != null && id.equals(parentId)) {
                    if (CollectionUtils.isEmpty(prentMenu.getChildren()))
                        prentMenu.initChildren();

                    prentMenu.getChildren().add(menu);

                }
            }
        }
        return treeMenus;
    }

    @Override
    public List<MenuViewVo> findTreeMeta(String username) {
        return findMetaView(username, 0);
    }


    /**
     *   构建路由
     * @param routes
     * @param <T>
     * @return
     */
    public static <T> List<VueRouter<T>> buildVueRouter(List<VueRouter<T>> routes) {
        if (routes == null) {
            return null;
        }
        List<VueRouter<T>> topRoutes = new ArrayList<>();
       // VueRouter<T> router = new VueRouter<>();
        for (VueRouter<T> route : routes) {
            String parentId = route.getParentId();
            if (parentId == null || parentId.equals(0)) {
                topRoutes.add(route);
                continue;
            }
            for (VueRouter<T> parent : routes) {
                String id = parent.getId();
                if (id != null && id.equals(parentId)) {
                    if (parent.getChildren() == null)
                        parent.initChildren();
                    parent.getChildren().add(route);
                    parent.setAlwaysShow(true);
                    parent.setHasChildren(true);
                    route.setHasParent(true);
                    parent.setHasParent(true);
                }
            }
        }

        return topRoutes;
    }
}
